use windows_sys::Win32::Foundation::NTSTATUS;

use crate::wow64_callback::FunctionAddressTable;
use core::ffi::c_void;

pub static mut FUNCTION_ADDRESS_TABLE: FunctionAddressTable = FunctionAddressTable {
    nt_allocate_virtual_memory_address: 0,
    nt_protect_virtual_memory_address: 0,
    nt_write_virtual_memory: 0,
};

// Function to return SSN
// HARDCODED -> use manual sys extract technique !

pub fn return_functions_ssn(instruction_pointer: u64) -> u64 {
    let nt_function_address = instruction_pointer - 3;

    unsafe {

        if nt_function_address == FUNCTION_ADDRESS_TABLE.nt_allocate_virtual_memory_address {
            0x18 // NTALLOCATEVIRTUALMEMORY 
        } else if nt_function_address == FUNCTION_ADDRESS_TABLE.nt_protect_virtual_memory_address {
            0x50 // NTPROTECTVIRTUALMEMORY
        } else {
            0
        }
    }
}

pub fn return_syscall_instruction_address(instruction_pointer: u64) -> u64 {

    let opcodes = [0x0F_u8, 0x05_u8];

    for i in 0..25 {
        let ptr = (instruction_pointer + i) as *const u8;
        unsafe {
            if *ptr == opcodes[0] && *(ptr.offset(1)) == opcodes[1] {
                return instruction_pointer + i;
            }
        }
    }

    0
}


pub type NtAllocateVirtualMemoryFn = unsafe extern "system" fn(
    *mut c_void,
    *mut *mut c_void,
    usize,
    *mut usize,
    u32,
    u32,
) -> NTSTATUS;

pub type NtProtectVirtualMemoryFn = unsafe extern "system" fn(
    *mut c_void, 
    *mut *mut c_void, 
    *mut usize, 
    u32, 
    *mut u32
) -> NTSTATUS;

// pub type NtWriteVirtualMemoryFn = unsafe extern "system" fn(
//     *mut c_void,
//     *mut c_void,
//     *mut c_void,
//     usize,
//     *mut usize,
// ) -> NTSTATUS;
